/*
 * Package il.ac.biu.cs.grossmm.impl.activeData
 * File DataPointLink.java
 * 
 * This is a part of presence service framework prototype. 
 * See javadoc for more information.
 *  
 * Copyright (C) 2006 Grossmann Mark
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package il.ac.biu.cs.grossmm.impl.activeData;

import il.ac.biu.cs.grossmm.api.flow.NotificationProvider;
import il.ac.biu.cs.grossmm.api.flow.Subscriber;
import il.ac.biu.cs.grossmm.api.flow.Track;
import il.ac.biu.cs.grossmm.api.keys.Key;
import il.ac.biu.cs.grossmm.api.keys.KeyPattern;
import il.ac.biu.cs.grossmm.impl.keys.PatternMatcher;

public class DataPointLink<N> implements Comparable {
	private final SubscriptionPointImpl<N> subscriptionPoint;

	private final NotificationProvider<N> notificationProvider;

	private final ConversionProcessor[] converters;

	private final double priority;

	private KeyPattern pattern;

	/**
	 * 
	 * @param subscriptionPoint
	 * @param np
	 * @param converters
	 * @param pattern
	 * @param priority
	 */
	public DataPointLink(SubscriptionPointImpl<N> subscriptionPoint,
			NotificationProvider<N> np, ConversionProcessor[] converters,
			KeyPattern pattern, double priority) {
		this.subscriptionPoint = subscriptionPoint;
		this.notificationProvider = np;
		this.converters = converters;
		this.pattern = pattern;
		this.priority = priority;
	}

	@SuppressWarnings("unchecked")
	public SubscriptionImpl<N> subscribe(Subscriber<N> subscriber, Key key,
			Track track) {
		if (converters == null || converters.length == 0) {
			// no data conversion needed
			return (SubscriptionImpl<N>) notificationProvider.subscribe(subscriber, key, track);
		} else {
			// use conversion chain
			ConversionProcessor firstConverter = converters[0];
			return firstConverter.subscribe(key, converters, 0,
					notificationProvider, subscriber, track);
		}
	}

	public NotificationProvider getProvider() {
		return notificationProvider;
	}

	public int compareTo(Object o) {
		DataPointLink dl = (DataPointLink) o;

		// reverse ordering
		return (int) Math.signum(dl.priority - priority);
	}

	public boolean matches(Key key) {
		if (pattern == null)
			return true;

		return PatternMatcher.matches(pattern, key);
	}

	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer("link " + priority + " from ");
		sb.append(subscriptionPoint);
		sb.append(" to ");
		sb.append(notificationProvider);
		sb.append(" with pattern ");
		sb.append(pattern == null ? "*" : pattern);

		if (converters != null) {
			for (ConversionProcessor cp : converters)
				sb.append(cp);

			sb.append("\n");
		}

		return sb.toString();
	}
}
